/***
 * Online Store Retailer
 *
 * Copyright (C) 2013 Integrator Project N.2 Class
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors: Leaders: Johan Santacruz, Sebasti�n Santamaria
 *          Quality assurance: Miguel Jimen�z, Juan David Lenis, Johnatan Zarama
 *          A Developers: Sebasti�n Cortes, Luis Dominguez
 *          B Developers: Fabi�n Caicedo, Andr�s Agredo, Javier Vasquez, Nicol�s Lema          
 */
package com.pi2.osr.war.backingbean;

import java.math.BigDecimal;

import java.math.BigInteger;
import java.util.ArrayList;


import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import org.primefaces.event.RowEditEvent;

import com.pi2.osr.ejb.custom.CarritoCompras;
import com.pi2.osr.ejb.custom.CompraCustom;
import com.pi2.osr.ejb.custom.UsuarioCustom;
import com.pi2.osr.ejb.entities.Producto;
import com.pi2.osr.ejb.entities.Usuario;
import com.pi2.osr.ejb.entities.Detalletemporal;
import com.pi2.osr.ejb.utilities.OSRException;

@ManagedBean(name="CarritoBean")
@SessionScoped
public class CarritoBackingBean {

	@EJB
	private CarritoCompras carrito;

	@EJB
	private UsuarioCustom usuario;

	@EJB
	private CompraCustom compra;

	/**
	 * es el usuario que se encuentra autenticado
	 */
	private Usuario usuario2=null;

	/**
	 * son los productos que el usuario ha agregado al carro de compras
	 */
	private ArrayList<Detalletemporal> detalles = new ArrayList<Detalletemporal> ();

	/**
	 * Se inicializan los atributos
	 */
	@PostConstruct
	public void Init()
	{
		//usuario2 = usuario.getUsuarioFindByIdusuario(new BigDecimal(4)).get(0);

		FacesContext context = FacesContext.getCurrentInstance();
		HttpSession session = (HttpSession) context.getExternalContext().getSession(false);

		if(session!=null){

			usuario2 = (Usuario)session.getAttribute("user");

			if(usuario2!=null){

				try {
					detalles = new ArrayList<Detalletemporal>(carrito.buscarCarrito(usuario2));

				} catch (Exception e) {
					FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Carga", "Error al cargar el carro");  
					FacesContext.getCurrentInstance().addMessage(null, msg); 
				}
			}
		}

	}

	/**
	 * Se obtienen los productos del carro
	 */
	public ArrayList<Detalletemporal> getDetalles() {
		return detalles;
	}

	/**
	 * Se asignan los productos del carro
	 */
	public void setDetalles(ArrayList<Detalletemporal> detalles) {
		this.detalles = detalles;
	}

	/**
	 * Se elimina un producto del carro de compras
	 */
	public void eliminarProducto(int row)
	{
		try {

			if(usuario2==null){
				detalles.remove(row);
			} else {
				Detalletemporal det = detalles.get(row);
				carrito.eliminarProducto(det);
				detalles.remove(row);
			}

		} catch (Exception e) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Eliminar Producto", "El producto no pudo ser eliminado");  
			FacesContext.getCurrentInstance().addMessage(null, msg); 
		}

	}

	/**
	 *vac�a el carrito de compras
	 */
	public String vaciarCarrito() {
		if(detalles.size() > 0) {
			try {

				if(usuario2 != null){
					carrito.reset(usuario2);
					detalles = new ArrayList<Detalletemporal>();
				} else {
					detalles = new ArrayList<Detalletemporal>();
				}

			} catch (Exception e) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Vaciar", "su carro no pudo ser vaciado");  
				FacesContext.getCurrentInstance().addMessage(null, msg); 
			}
		}

		return null;
	}

	/**
	 *Se ejecuta cuando el evento de edicion se dispara en la vista. Aqui se cambia la cantidad de un producto en el carro de compras
	 */
	public void onEdit(RowEditEvent event) {  

		Detalletemporal det = (Detalletemporal) event.getObject();

		try {
			if(usuario2!=null)
			{
				carrito.aumentarCantidad(det);
			}

		} 
		catch (Exception e) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cambio", "Su cambio no fue guardado");  
			FacesContext.getCurrentInstance().addMessage(null, msg); 
		}
	}  

	public void onCancel(RowEditEvent event) {  

	} 

	/**
	 * Realiza la compra de los productos en el carro de compras
	 * @return
	 */
	public String comprar()
	{
		if(detalles.size()>0 && usuario2!=null)
		{
			try {

				compra.consolidarCompra(detalles, usuario2);

				detalles = new ArrayList<Detalletemporal>();

				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Compra", "su compra fue existosa");  
				FacesContext.getCurrentInstance().addMessage(null, msg);  

			} catch (Exception e) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Compra", "No pudimos completar su solicitud");  
				FacesContext.getCurrentInstance().addMessage(null, msg); 
			}
		}
		else if(detalles.size()>0)
		{
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Iniciar Sesion", "Debes iniciar sesion para realizar compras");  
			FacesContext.getCurrentInstance().addMessage(null, msg); 
		}


		return null;
	}

	/**
	 * Agrega un producto al carro de compras
	 */
	public void agregarCar(Producto producto) {

		boolean esta =false;

		for(int i=0;i<detalles.size() && !esta;i++)
		{
			Detalletemporal det = detalles.get(i);
			BigDecimal idProd = det.getIdproducto().getIdproducto();
			if(idProd.equals(producto.getIdproducto()))
			{
				esta = true;
				try {
					det.setCantidad(det.getCantidad().add(BigInteger.ONE));
					if(usuario2!=null)
					{
						carrito.aumentarCantidad(det);
					}
					
					FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Producto", "Se agrego el producto");  
					FacesContext.getCurrentInstance().addMessage(null, msg); 
				} catch (Exception e) {
					FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Producto", "No pudimos agregar el producto");  
					FacesContext.getCurrentInstance().addMessage(null, msg); 
				}
			}
		}

		if(!esta)
		{
			Detalletemporal detalletemporal = new Detalletemporal();
			detalletemporal.setIdproducto(producto);
			detalletemporal.setCantidad(BigInteger.valueOf(1));
			detalletemporal.setIdusuario(usuario2);

			ArrayList<Detalletemporal> s = new ArrayList<Detalletemporal>();
			s.add(detalletemporal);
			try {
				if(usuario2!=null)
				{
					carrito.guardarCarrito(s);
					//me toca volver a llamar para obtener los ids de los nuevos
					detalles = new ArrayList<Detalletemporal>(carrito.buscarCarrito(usuario2));
				}
				else
				{
					detalles.add(detalletemporal);
				}

				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Producto", "Se agrego el producto");  
				FacesContext.getCurrentInstance().addMessage(null, msg); 
			} catch (Exception e) {
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Producto", "Error agregando el producto");  
				FacesContext.getCurrentInstance().addMessage(null, msg); 
			}
		}

		FacesContext context = FacesContext.getCurrentInstance(); 
		context.addMessage(null, new FacesMessage("Carrito de compras", "El producto se agreg� correctamente"));  

	}

	/**
	 * carga el carro cuando el usuario inicia la sesion
	 */
	public void cargarCarro()
	{
		FacesContext context = FacesContext.getCurrentInstance();
		HttpSession session = (HttpSession) context.getExternalContext().getSession(false);

		if(session!=null)
		{
			usuario2 = (Usuario)session.getAttribute("user");

			if(usuario2!=null)
			{
				try {

					if(detalles.isEmpty())
					{
						detalles = new ArrayList<Detalletemporal>(carrito.buscarCarrito(usuario2));
					}
					else
					{
						ArrayList<Detalletemporal> detalles2 = new ArrayList<Detalletemporal>(carrito.buscarCarrito(usuario2));
						if(guardarNuevos(detalles2))
						{
							//me toca volver a llamar para obtener los ids de los nuevos
							detalles = new ArrayList<Detalletemporal>(carrito.buscarCarrito(usuario2));
						}
						
						
					}

				} catch (Exception e) {
					FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Carga", "Error al cargar el carro");  
					FacesContext.getCurrentInstance().addMessage(null, msg); 
				}
			}
		}


	}
	
	/**
	 * guarda los detalles no tenia guardados
	 */
	public boolean guardarNuevos(ArrayList<Detalletemporal> detalles2)
	{
		ArrayList<Detalletemporal> s = new ArrayList<Detalletemporal>();
		for(Detalletemporal det:detalles)
		{
			boolean existe = false;

			for(Detalletemporal det2:detalles2)
			{
				if(det.getIdproducto().getIdproducto().equals(det2.getIdproducto().getIdproducto()))
				{
					existe = true;
					
					if(!det.getCantidad().equals(det2.getCantidad()))
					{
						det2.setCantidad(det.getCantidad());
						try {
							carrito.aumentarCantidad(det2);
						} catch (OSRException e) {
							FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Carga", "Error al cargar el carro");  
							FacesContext.getCurrentInstance().addMessage(null, msg); 
						}
					}
					
					break;
				}
				
			}
			if(!existe)
			{
				det.setIdusuario(usuario2);
				s.add(det);	
			}
		}
		
		try {
			carrito.guardarCarrito(s);
			
			
		} catch (OSRException e) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Carga", "No pudimos guardar los producto nuevos");  
			FacesContext.getCurrentInstance().addMessage(null, msg); 
		}
		
		return !s.isEmpty();
	}

	/**
	 *verifica si un producto que el usuario habia guardado existe en su carro de compras 
	 */
	private boolean existeEnCarro(Detalletemporal detalle)
	{
		boolean existe = false;

		for(Detalletemporal det:detalles)
		{
			if(det.getIdproducto().getIdproducto().equals(detalle.getIdproducto().getIdproducto()))
			{
				existe = true;
				break;
			}
			
		}
		
		return existe;
	}

	/**
	 * borra el carrito de compras
	 */
	public void borrar()
	{
		detalles = new ArrayList<Detalletemporal>();
		usuario2 = null;
	}

	public boolean mostrarBotonCompra()
	{

		return usuario2!=null;
	}

}
